package se.bluebrim.jni.example;

import java.io.File;
import java.lang.reflect.Field;

import org.apache.commons.io.FilenameUtils;

/**
 * 
 * @author Goran Stack
 * 
 */
public class HelloWorldApp {

	public static void main(String[] args) {
		new HelloWorldApp().run(args);
	}
	
	protected final void run(String[] args)
	{
		setJavaLibraryPath(new File(getLibDirectoryRelativePath()).getPath());
		loadNativeLibraries();
		new HelloWorld().printHello();		
	}
	
	private void loadNativeLibraries()
	{
		File nativeLibDir = new File(System.getProperty("java.library.path"));
		if (nativeLibDir.exists() && nativeLibDir.isDirectory())
		{
			File[] files = nativeLibDir.listFiles();
			for (File file : files) {
				System.loadLibrary(FilenameUtils.getBaseName(file.getName()));
			}
		} else
			throw new RuntimeException("Native library \"" + nativeLibDir.getPath() + "\" is missing");
	}

	protected String getLibDirectoryRelativePath() {
		return "native-lib";
	}

	/**
	 * <a href="http://blog.cedarsoft.com/2010/11/setting-java-library-path-programmatically/">Setting "java.library.path" programmatically</a>
	 */
	private void setJavaLibraryPath(String path) {
		System.setProperty("java.library.path", path);
		Field fieldSysPath;
		try {
			fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
		} catch (SecurityException e) {
			throw new RuntimeException(e);
		} catch (NoSuchFieldException e) {
			throw new RuntimeException(e);
		}
		fieldSysPath.setAccessible(true);
		try {
			fieldSysPath.set(null, null);
		} catch (IllegalArgumentException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}

}
